<template>
  <div>
    <h1>使用 JS 把 list 转化为 tree</h1>
    {{ treeData }}
  </div>
</template>

<script>

export default {
  data() {
    return {
      treeData: [],
      tree: [
        {
          id: '1',
          name: '节点1',
          children: [
            {
              id: '1-1',
              name: '节点1-1'
            }
          ]
        },
        {
          id: '2',
          name: '节点2',
          children: [
            {
              id: '2-1',
              name: '节点2-1'
            },
            {
              id: '2-2',
              name: '节点2-2',
              children: [
                {
                  id: '2-2-1',
                  name: '节点2-2-1'
                }
              ]
            }
          ]
        },
        {
          id: '3',
          name: '节点3'
        },
        {
          id: '4',
          name: '节点4'
        }
      ],
    }
  },
  created() {
    let menu = [
      { menuId: "11", parentId: "" }
    ]

    let list = [
      { id: "0000", parentId: "", name: "总行" },
      { id: "000", parentId: "", name: "总行2" },
      { id: "0001", parentId: "0000", name: "分行1" },
      { id: "0002", parentId: "0000", name: "分行2" },
      { id: "0003", parentId: "0001", name: "支行1" },
      { id: "0004", parentId: "0001", name: "支行2" },
      { id: "0005", parentId: "00000", name: "支行2" },

    ];
    // 获取ISO8601
    // var d = new Date();
    // d.setHours(d.getHours(), d.getMinutes() - d.getTimezoneOffset());
    // console.log(d.toISOString())

    // console.log(new Date().toISOString());
    // let tree = this.list2Tree(list);
    // let tree = this.list2Tree3(list);
    // this.treeData = tree
    // console.log(tree);
    // this.dynamicPropertyName();//动态设置属性名称
    // let result = this.auth(`system/user/userList`, `useradd`);
    // console.log("result", result);

  },
  mounted() {
    this.bfsTreeEach(this.tree, node => {
      console.log(node.name)
    })

    this.treeIterator(this.tree, node => {
      node.disabled = true;
      console.log(node)
    })
    console.log(this.tree);

  },
  methods: {
    /**
     * 遍历树结构数据
     * 广度优先
     */
    bfsTreeEach(tree, func) {
      let node, nodes = tree.slice()
      while (node = nodes.shift()) {
        func(node)
        if (node.children && node.children.length) {
          nodes.push(...node.children)
        }
      }
    },

    /**
     * 遍历树结构数据
     * 深度优先遍历（DFS）
     */
    treeIterator(tree, func) {
      tree.forEach((node) => {
        func(node)
        node.children && this.treeIterator(node.children, func)
      })
    },

    auth(path, btnCode) {
      let menus = [
        { id: "001", name: "人员管理", path: "system/user/userList", buttonList: [{ code: "useradd", name: "新增" }] },
        { id: "002", name: "权限管理", path: "system/auth/authList" }
      ]
      if (path && btnCode && menus) {
        for (let i = 0; i < menus.length; i++) {
          if (menus[i].path === path) {
            console.log(menus[i]);
            if (menus[i].buttonList) {
              for (let j = 0; j < menus[i].buttonList.length; j++) {
                if (menus[i].buttonList[j].code === btnCode) {
                  return true;
                }
              }
            }
          }
        }
      }
      return false
    },
    /**
     * 第一种
     */
    list2Tree(list) {
      let map = {};
      list.forEach(item => {
        if (!map[item.id]) {
          map[item.id] = item;
        }
      });

      list.forEach(item => {
        if (item.parentId !== "") {
          map[item.parentId].children ? map[item.parentId].children.push(item) : map[item.parentId].children = [item];
        }
      });

      return list.filter(item => {
        if (item.parentId === "") {
          return item;
        }
      })
    },
    /**
     * list list集合
     * parentId 父级ID
     * 添加了undefined判断
     */
    list2Tree2(list, parentId = "") {
      const obj = {};
      list.forEach(item => {
        item.children = []
        obj[item.id] = item
      })
      return list.filter(item => {
        if (item.parentId !== parentId) {
          if (obj[item.parentId] !== undefined) {
            // 如果上级编号在list中找不到会报错，添加undefined判断，筛选有问题的数据
            obj[item.parentId].children.push(item)
          } else {
            console.log("上级不存在，此条数据有问题", item);
          }
          return false;
        }
        return true;
      })
    },
    /**
     * 动态属性名
     */
    dynamicPropertyName() {
      // 1. 点符号
      // 使用点符号可以直接在对象上设置属性名，但是属性名必须是一个有效的标识符。
      // 示例1：动态设置属性名为变量值
      const propertyName = 'name';
      const obj = {};
      obj[propertyName] = 'John';
      console.log(obj); // 输出: John
      // 示例2：动态设置属性名为表达式结果
      const obj2 = {};
      obj2['prop' + 'erty'] = 'value';
      console.log(obj2.property); // 输出: value

      // 2. 方括号符号
      // 使用方括号符号可以在对象上设置任意字符串作为属性名，包括非标识符字符。
      // 示例1：动态设置属性名为变量值
      const propertyName3 = 'name';
      const obj3 = {};
      obj3[propertyName3] = 'John';
      console.log(obj3['name']); // 输出: John

      // 示例2：动态设置属性名为表达式结果
      const obj4 = {};
      obj4['prop' + 'erty'] = 'value';
      console.log(obj4['property']); // 输出: value

    },
    /**
     * 第三种，这种方法为第二种的升级版本
     */
    list2Tree3(list, parentId = "", idName = "id", parentIdName = "parentId") {
      const obj = {};
      list.forEach(item => {
        item.children = []
        obj[item[idName]] = item
      })
      console.log(obj);
      return list.filter(item => {
        if (item[parentIdName] !== parentId) {
          if (obj[item[parentIdName]] !== undefined) {
            // 如果上级编号在list中找不到会报错，添加undefined判断，筛选有问题的数据
            obj[item[parentIdName]].children.push(item)
          } else {
            console.log("上级不存在，此条数据有问题", item);
          }
          return false;
        }
        return true;
      })
    },

    /**
     * 
     */
    transformMenu(list) {
      let menuObj = {},
        result = list || [];

      if (result.length) {
        result
          .sort((a, b) => {
            return parseInt(a.seq, 10) - parseInt(b.seq, 10);
          })
          .map(i => {
            !i.parentId && (i.parentId = "");
            let p = menuObj[i.parentId];
            if (!p) {
              p = menuObj[i.parentId] = {
                id: i.parentId,
                children: []
              };
            } else {
              !p.children && (p.children = []);
            }
            let item = menuObj[i.menuId] || {
              id: i.menuId
              //children:[]
            };
            item.parentId = i.parentId || "";
            item.name = i.menuId;
            item.path = i.menuId;

            item.deploy = i.deploy;

            i.path && (item.component = i.path);
            item.meta = {
              title: i.name,
              icon: i.icon
            };
            menuObj[i.menuId] = item;
            p.children.push(item);
          });

        Object.keys(menuObj)
          .filter(e => !menuObj[e].children)
          .map(e => delete menuObj[e]);

        // menuObj[""].children[0].meta.icon = 'el-icon-user-solid'
        return menuObj[""].children;
      } else {
        return [];
      }
    },



  },
}
</script>

<style scoped>
</style>